package model;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import service.EmpregadoService;
import util.HibernateUtil;

public class EmpregadoTeste {
	
	private EntityManagerFactory emf;
	private EntityManager entityManager;
	private EmpregadoService empregadoDao;
	private static final String PERSISTENCE_NAME = "JPAExemplo";
	
	@Before
	public void setUp() {
		HibernateUtil.setUp();
		emf = Persistence.createEntityManagerFactory(PERSISTENCE_NAME);
		entityManager  = emf.createEntityManager();
		entityManager.getTransaction().begin();
		empregadoDao = new EmpregadoService(entityManager);
	}
	
	//XXX Lembrar de dropar o database sempre que executar o teste.
	//XXX Lembrar de criar o database sempre que for executar o teste novamente.
	
	@Test
	public void test_case_insert() {
		
		//Adiciona o primeiro empregado.
		Empregado empregado1 = criaEmpregado("Peter Tosh", 150); //id = 1;
		empregadoDao.insereEmp(empregado1);
		entityManager.getTransaction().commit();
		
		List<Empregado> listaEmpregados1 = empregadoDao.listaEmpregados();
		Assert.assertEquals(1, listaEmpregados1.size());
		
		//Adiciona o segundo empregado.
		entityManager.getTransaction().begin();
		Empregado empregado2 = criaEmpregado("Bob Marley", 1000); //id = 2
		empregadoDao.insereEmp(empregado2);
		entityManager.getTransaction().commit();
		
		List<Empregado> listaEmpregados2 = empregadoDao.listaEmpregados();
		Assert.assertEquals(2, listaEmpregados2.size());
		
		//Atualiza o salario do primeiro empregado.
		entityManager.getTransaction().begin();
		empregadoDao.aumentaSalario(1, 200);
		entityManager.getTransaction().commit();
		
		entityManager.getTransaction().begin();
		Empregado empregado1Resgatado = empregadoDao.findEmpregado(1);
		entityManager.getTransaction().commit();
		
		Assert.assertEquals(350, empregado1Resgatado.getSalario());
		
		//Atualiza o salario do primeiro empregado.
		entityManager.getTransaction().begin();
		empregadoDao.aumentaSalario(2, 500);
		entityManager.getTransaction().commit();
		
		entityManager.getTransaction().begin();
		Empregado empregado2Resgatado = empregadoDao.findEmpregado(2);
		entityManager.getTransaction().commit();
		
		Assert.assertEquals(1500, empregado2Resgatado.getSalario());
		
		//encontar o usuario peter tosh
		entityManager.getTransaction().begin();
		Empregado empregadoPeter = empregadoDao.findEmpregado(1);
		entityManager.getTransaction().commit();
		
		Assert.assertEquals("Peter Tosh", empregadoPeter.getNome());
		
		//Encotrar todos os usuarios
		entityManager.getTransaction().begin();
		List<Empregado> listaEmpregados = empregadoDao.listaEmpregados();
		Assert.assertEquals("Peter Tosh",listaEmpregados.get(0).getNome());
		Assert.assertEquals("Bob Marley",listaEmpregados.get(1).getNome());
		entityManager.getTransaction().commit();
		
		//altera nome de bob marley
		entityManager.getTransaction().begin();
		empregadoDao.alteraNomeEmp(2, "Zig Marley");
		entityManager.getTransaction().commit();
		
		// Encotrar todos os usuarios
		entityManager.getTransaction().begin();
		List<Empregado> listaEmpregadosModificada = empregadoDao.listaEmpregados();
		Assert.assertEquals("Peter Tosh", listaEmpregadosModificada.get(0).getNome());
		Assert.assertEquals("Zig Marley", listaEmpregadosModificada.get(1).getNome());
		entityManager.getTransaction().commit();
		
		//deleta peter
		entityManager.getTransaction().begin();
		empregadoDao.deletaEmp(1);
		entityManager.getTransaction().commit();
		
		List<Empregado> listaEmpregadosFinal = empregadoDao.listaEmpregados();
		Assert.assertEquals(1, listaEmpregadosFinal.size());
		
		//Resultado final
		//EmpNome: Zig Marley - Salario: 1500
		
		emf.close();
	}
	
	
	private Empregado criaEmpregado(String nome, long salario) {
		Empregado emp = new Empregado();
		emp.setNome(nome);
		emp.setSalario(salario);
		return emp;
	}

}
